﻿using System;
using System.IO;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using Core;
using Microsoft.Win32;
using System.Numerics;
using System.Collections;
using System.Collections.Generic;

namespace Editor
{
    /// <summary>
    /// Interaction logic for Editor.xaml
    /// </summary>
    public partial class Editor : UserControl
    {
        public static int BYTE_TYPE = 0;
        public static int HEX_TYPE = 1;

        #region Text Type
        private int textType = Editor.BYTE_TYPE;
        public int TextType
        {
            set
            {
                if (value != BYTE_TYPE && value != HEX_TYPE)
                {
                    textType = BYTE_TYPE;
                }
                else
                {
                    textType = value;
                }
            }
            get { return textType; }
        }
        #endregion

        #region Set Text
        public void SetText(string text)
        {
            // Set text box
            if (textType == HEX_TYPE)
            {
                textBox.Text = ToHex(text);
            }
            else
            {
                textBox.Text = text;
            }
        }
        #endregion

        #region Get Text
        public string GetText()
        {
            if (textType == HEX_TYPE)
            {
                return ToString(textBox.Text);
            }
            else
            {
                return textBox.Text;
            }
        }
        #endregion

        #region File Name
        private string fileName = null;
        public string FileName
        {
            get { return fileName; }
            set { fileName = value; }
        }
        #endregion

        private MemoryStream stream;

        public Editor()
        {
            InitializeComponent();
        }

        #region Event Click
        private void buttonNew_Click(object sender, RoutedEventArgs e)
        {
            clear();
        }

        private void buttonOpen_Click(object sender, RoutedEventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.RestoreDirectory = true;

            // Show Open File Dialog
            if (ofd.ShowDialog() == true)
            {
                fileName = ofd.FileName;
                if (fileName != null)
                {
                    if (Path.GetExtension(fileName) == ".txt")
                    {
                        // read file txt
                        readFileTxt(fileName);
                    }
                    else
                    {
                        // read file
                        readFile(fileName);
                    }
                }
            }
        }

        private void buttonSave_Click(object sender, RoutedEventArgs e)
        {
            SaveFileDialog sfd = new SaveFileDialog();
            sfd.RestoreDirectory = true;

            // Show save file dialog
            if (sfd.ShowDialog() == true)
            {
                fileName = sfd.FileName;

                if (fileName != null)
                {
                    // Save file
                    saveFile(fileName);
                }
            }
        }
        #endregion

        #region File Management
        private void readFile(string fileName)
        {
            // Make File Stream
            FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);

            // Create temporary
            long length = fs.Length;
            byte[] temp = new byte[length];

            // Read File
            fs.Position = 0;
            fs.Read(temp, 0, (int)length);

            // Close file stream
            fs.Close();

            // Set stream
            stream = new MemoryStream(temp);

            // Set Text
            SetText(Converter.BytesToString(stream.ToArray()));
        }

        private void readFileTxt(string fileName)
        {
            // Make File Stream
            FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);

            // Create temporary
            List<byte> bytes = new List<byte>();
            int temp = fs.ReadByte();

            // Iterate, add to container and read next
            while (temp > 0)
            {
                bytes.Add((byte)temp);
                temp = fs.ReadByte();
            }

            // Close file stream
            fs.Close();

            // Set Stream
            stream = new MemoryStream(bytes.ToArray());

            // Set Text
            SetText(Converter.BytesToString(stream.ToArray()));
        }

        private void clear()
        {
            textBox.Text = "";
        }

        private void saveFile(String fileName)
        {
            if (fileName != null)
            {
                stream = new MemoryStream(Converter.ToBytes(GetText()));
                SaveMemoryStream(stream, fileName);
            }
        }

        private void SaveMemoryStream(MemoryStream ms, String fileName)
        {
            FileStream outStream = File.OpenWrite(fileName);
            ms.WriteTo(outStream);
            outStream.Flush();
            outStream.Close();
        }
        #endregion

        #region Converter
        private string ToHex(string s)
        {
            if (s == null || s.Length < 1)
            {
                return "";
            }

            StringBuilder sb = new StringBuilder();
            string[] ss = s.Split(' ');
            int bound = ss.Length;

            for (int i = 0; i < bound; ++i)
            {
                BigInteger bi = BigInteger.Parse(ss[i]);
                sb.Append(bi.ToString("X") + " ");
            }
            sb.Remove(sb.Length - 1, 1);
            Console.WriteLine(s);

            return sb.ToString();
        }

        private string ToString(string hex)
        {
            hex = hex.Trim();

            if (hex.Length < 1)
            {
                return "";
            }

            string[] split = hex.Split(' ');
            int bound = split.Length;
            StringBuilder sb = new StringBuilder();

            for (int i = 0; i < bound; ++i)
            {
                if (split[i] != "")
                {
                    BigInteger temp = new BigInteger();
                    if (BigInteger.TryParse(split[i], System.Globalization.NumberStyles.HexNumber, null, out temp))
                    {
                        sb.Append(temp.ToString());
                        sb.Append(" ");
                    }
                }
            }

            // Remove last 'space'
            if (sb.Length > 0)
            {
                sb.Remove(sb.Length - 1, 1);
            }
            Console.WriteLine(sb.ToString());
            return sb.ToString();
        }
        #endregion
    }
}